Os Dados¶
[1]:
import pandas as pd
# reading csv file
BRdata = pd.read_csv("./PG_IMT/DadosEpidemia/CoVid19.csv")
BRdata.head()
[1]:
date | country | state | city | newDeaths | deaths | newCases | totalCases | deathsMS | totalCasesMS | deaths_per_100k_inhabitants | totalCases_per_100k_inhabitants | deaths_by_totalCases | recovered | suspects | tests | tests_per_100k_inhabitants | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 2020-02-25 | Brazil | SP | TOTAL | 0 | 0 | 1 | 1 | 0 | 0 | 0.0 | 0.00218 | 0.0 | NaN | NaN | NaN | NaN |
1 | 2020-02-25 | Brazil | TOTAL | TOTAL | 0 | 0 | 1 | 1 | 0 | 0 | 0.0 | 0.00048 | 0.0 | NaN | NaN | NaN | NaN |
2 | 2020-02-26 | Brazil | SP | TOTAL | 0 | 0 | 0 | 1 | 0 | 1 | 0.0 | 0.00218 | 0.0 | NaN | NaN | NaN | NaN |
3 | 2020-02-26 | Brazil | TOTAL | TOTAL | 0 | 0 | 0 | 1 | 0 | 1 | 0.0 | 0.00048 | 0.0 | NaN | NaN | NaN | NaN |
4 | 2020-02-27 | Brazil | SP | TOTAL | 0 | 0 | 0 | 1 | 0 | 1 | 0.0 | 0.00218 | 0.0 | NaN | NaN | NaN | NaN |
Filtrando e limpando os dados¶
[2]:
is_SP = BRdata['state']=='TOTAL'
SPdata = BRdata[is_SP]
# SPdata = SPdata.fillna(0)
SPLimpo = SPdata[SPdata.recovered.notnull()]
SPLimpo.head()
[2]:
date | country | state | city | newDeaths | deaths | newCases | totalCases | deathsMS | totalCasesMS | deaths_per_100k_inhabitants | totalCases_per_100k_inhabitants | deaths_by_totalCases | recovered | suspects | tests | tests_per_100k_inhabitants | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
321 | 2020-03-23 | Brazil | TOTAL | TOTAL | 9 | 34 | 358 | 1952 | 34 | 1891 | 0.01618 | 0.92887 | 0.01742 | 8.0 | 15867.0 | NaN | NaN |
349 | 2020-03-24 | Brazil | TOTAL | TOTAL | 13 | 47 | 303 | 2255 | 46 | 2201 | 0.02237 | 1.07306 | 0.02084 | 20.0 | 17700.0 | NaN | NaN |
377 | 2020-03-25 | Brazil | TOTAL | TOTAL | 12 | 59 | 311 | 2566 | 57 | 2433 | 0.02808 | 1.22105 | 0.02299 | 27.0 | 27227.0 | NaN | NaN |
405 | 2020-03-26 | Brazil | TOTAL | TOTAL | 18 | 77 | 424 | 2990 | 77 | 2915 | 0.03664 | 1.42281 | 0.02575 | 42.0 | 48793.0 | NaN | NaN |
433 | 2020-03-27 | Brazil | TOTAL | TOTAL | 16 | 93 | 486 | 3476 | 92 | 3417 | 0.04425 | 1.65408 | 0.02675 | 42.0 | 50684.0 | NaN | NaN |
[3]:
from datetime import datetime
first_date = SPLimpo["date"].iloc[0]
first_date = datetime.fromisoformat(first_date)
SPsir = SPLimpo[["totalCases", "deaths", "recovered"]].to_numpy()
SPsir[:,0:]
SPI = SPsir[:,0]
auxM = SPsir[:,1]
SPM = auxM
auxR = SPsir[:,2]
SPR = auxR
Visualizando a evolução¶
[4]:
from bokeh.models import Legend, ColumnDataSource, RangeTool, LinearAxis, Range1d
from bokeh.palettes import brewer, Inferno256
from bokeh.plotting import figure, show
from bokeh.layouts import column
from bokeh.io import output_notebook
output_notebook()
from datetime import timedelta
# Criando o vetor de tempo
t_num = range(len(SPM))
date_vec = [ first_date + timedelta(days=k) for k in t_num]
# Criando a figura
p = figure(
tools="hover",
title="Evolução do COVID",
x_axis_type='datetime',
y_axis_type="log",
plot_width=650,
plot_height=500
)
# Incluindo os dados de mortes
p.line(
date_vec, SPM,
legend_label="Mortes",
line_width=4,
line_cap="round",
color="#de425b"
)
# Incluindo os dados de infectados
p.line(
date_vec, SPI,
legend_label="Infectados",
line_width=4,
line_cap="round",
color="#ffd885"
)
# Incluindo os dados de recuperados
p.line(
date_vec, SPR,
legend_label="Removidos",
line_width=4,
line_cap="round",
color="#99d594"
)
p.grid.grid_line_alpha = 0
p.ygrid.band_fill_color = "olive"
p.ygrid.band_fill_alpha = 0.1
p.yaxis.axis_label = "Indivíduos"
p.xaxis.axis_label = "Dias"
p.legend.click_policy="hide"
p.legend.location = "bottom_right"
show(p)
Análise de um modelo com \(\beta\) variável no tempo¶
Uma outra forma de abordar a modelagme de dados é assumindo que a taxa de transmissão \(\beta\) é variante no tempo. Vamos, neste sentido, utilizar a abordagem elaborada por Mark Pollicott, Hao Wang & Howard (Howie) Weiss em 2012 - Extracting the time-dependent transmission rate from infection data via solution of an inverse ODE problem
Reescrevendo o conjunto de equações diferenciais que caracteriza o modelo é descrito abaixo. No modelo $:nbsphinx-math:beta`(t) - :nbsphinx-math:text{representa a taxa de transmissão ou taxa efetiva de contato}` $ e \(r - \text{a taxa de remoção ou recuperação.}\)
\[\begin{split}\begin{split}
\frac{dS(t)}{dt} & = -\mathbf{\beta(t)} S(t) I(t) \\
\frac{dI(t)}{dt} & = \mathbf{\beta(t)} S(t) I(t) - rI(t) \\
\frac{dR(t)}{dt} & = r I(t)
\end{split}\end{split}\]
Gostaríamos de identificar quais parâmetros \(\beta(t)\) e \(r\) resultam num melhor ajuste do modelo para os dados de S,I e R
Proposta de algoritmo para extração do \(\beta(t)\) a partir dos dados¶
- Interpolar os dados para suvizar eventuais variações gerando uma função \(f(t)\)
- Verificar a seguinte condição: \(\frac{f'(t)}{f(t)}>-r\). Neste algoritmo a taza de romação \(r\) é considerada constante.
- Determinando a função \(p(t) = \frac{f''(t)f(t)-f'^2(t)}{f(t)(f'(t)+rf(t))}\).
- Escolhendo um valor inicial para \(\beta(0)\) e determinando a integral \(P(t) = \int_0^t p(\tau) d\tau\).
- Verificar a seguinte condição: \(\beta(0) <\frac{1}{\int_0^t e^{P(s)}f(s) ds}\).
- O parâmetro \(\mathbf{\beta(t)}\) pode ser calculado por: \(\beta(t) = \frac{1}{\frac{e^{-P(t)}}{\beta(0)}-e^{-P(t)}\int_0^t e^{P(s)}f(s) ds}\).
1) Interpolar os dados para suvizar eventuais variações gerando uma função \(f(t)\)¶
[5]:
import numpy as np
from scipy.interpolate import Rbf, UnivariateSpline
# Generating weights for polynomial function with degree =2
weights = np.polyfit(t_num, SPI, 2)
rbf = Rbf(t_num, SPI, function='gaussian')
spline = UnivariateSpline(t_num, SPI)
print(weights)
# Generating model with the given weights
model = np.poly1d(weights)
t_sim = np.linspace(t_num[0], t_num[-1], 100)
# Prediction on validation set
pred = model(t_sim)
pred_rbf = rbf(t_sim)
pred_spline = spline(t_sim)
# We will plot the graph for 70 observations only
# Criando a figura
p = figure(
tools="hover",
title="Dados interpolados",
x_axis_type='datetime',
# y_axis_type="log",
plot_width=650,
plot_height=500
)
# Incluindo os dados de mortes
p.line(
t_num, SPI,
legend_label="Medidas",
line_width=4,
line_cap="round",
color="#de425b"
)
# Incluindo os dados de infectados
p.line(
t_sim, pred,
legend_label="Interpolação",
line_width=4,
line_cap="round",
color="#1e88e5"
)
p.line(
t_sim, pred_rbf,
legend_label="Interpolação - RBF",
line_width=3,
line_dash="dashed",
line_cap="round",
color="#512da8"
)
p.line(
t_sim, pred_spline,
legend_label="Interpolação - Spline",
line_width=3,
line_dash="dashed",
line_cap="round",
color="#00796b"
)
p.grid.grid_line_alpha = 0
p.ygrid.band_fill_color = "olive"
p.ygrid.band_fill_alpha = 0.1
p.yaxis.axis_label = "Indivíduos"
p.xaxis.axis_label = "Dias"
p.legend.click_policy="hide"
p.legend.location = "bottom_right"
show(p)
[ 67.47775863 -501.31086778 4785.98379386]